This section describes the constants, data type, and functions that are specific to clock components.
The Component Manager allows you to specify information about your component's capabilities in the componentFlags field of the component description structure. Apple has defined two component flags for clock components. These flags specify information about the capabilities of the clock component. You set these flags in the componentFlags field of your component's component description structure. You can use the following constants to manipulate these flags. You should set them appropriately for your clock. For more on the component description structure, see the chapter "Component Manager" in Inside Macintosh: More Macintosh Toolbox .
enum {
kClockRateIsLinear = 1,/* clock keeps constant
rate */
kClockImplementsCallBacks = 2/* clock supports callback
events */
};
You should set the componentFlags field appropriately in the component description structure that is associated with your clock component.
Apple has defined a type value and a number of subtype values for clock components. All clock components have a component type value of 'clok' . The component subtype value indicates the type of clock. You can use the following constants to specify these type and subtype values.
#define clockComponentType 'clok' /* clock component type */
#define systemTickClock 'tick' /* system tick clock */
#define systemSecondClock 'seco' /* system seconds clock */
#define systemMillisecondClock 'mill' /* system millisecond clock */
#define systemMicrosecondClock 'micr' /* system microsecond clock */
The clock component data structure is a private data structure. Programs that use your clock component never change the contents of this data structure directly. Your clock component provides functions that allow programs to use this data structure.
The callback header structure specifies the callback function for an operation. Your application can obtain callback function identifiers by calling its clock component's ClockNewCallBack function (described on ClockNewCallBack ).
The QTCallBackHeader data type defines the callback header structure.
struct QTCallBackHeader {
long callBackFlags; /* flags used by clock
component to communicate
scheduling data about
callback to Movie Toolbox */
long reserved1; /* reserved for use by Apple */
char qtPrivate[40]; /* reserved for use by Apple */
};
enum {
qtcbNeedsRateChanges = 1, /* clock needs to
know about rate
changes */
qtcbNeedsTimeChanges = 2 /* clock needs to
know about time
changes */
qtcbNeedsStartStopChanges
= 4 /* clock needs to
know about time
base changes */
};
This section describes the functions that are provided by clock components. These functions are described from the perspective of the Movie Toolbox, the entity that is most likely to call clock components. If you are developing a clock component, your component must behave as described here.
This section has been divided into the following topics:
If you are developing an application that uses clock components, you should read the next section, "Getting the Current Time."
If you are developing a clock component, you need to be familiar with all the functions described in this section.
Your application can call any clock component function at interrupt time, except for the ClockNewCallBack and ClockDisposeCallBack functions (described on ClockNewCallBack and ClockDisposeCallBack , respectively). In addition, your application should not call the Component Manager's OpenComponent and CloseComponent functions at interrupt time.
You can use the following constants to refer to the request codes for each of the functions that your clock component must support:
/* constants to refer to request codes for supported functions */
enum {
kClockGetTimeSelect = 0x1, /* ClockGetTime */
kClockNewCallBackSelect = 0x2,/* ClockNewCallBack */
kClockDisposeCallBackSelect = 0x3,/* ClockDisposeCallBack */
kClockCallMeWhenSelect = 0x4,/* ClockCallMeWhen */
kClockCancelCallBackSelect = 0x5,/* ClockCancelCallBack */
kClockRateChangedSelect = 0x6,/* ClockRateChanged */
kClockTimeChangedSelect = 0x7,/* ClockTimeChanged */
kClockSetTimeBaseSelect = 0x8,/* ClockSetTimeBase */
kClockStartStopChangedSelect = 0x9,/* ClockStartStopChanged */
kClockGetRateSelect = 0xA /* ClockGetRate */
};
Clock components provide a single function that allows the Movie Toolbox to obtain the current time.
The ClockGetTime function allows the Movie Toolbox to obtain the current time according to the specified clock.
pascal ComponentResult ClockGetTime (ComponentInstance aClock,
TimeRecord *out);
Applications that use QuickTime time bases may define callback functions that are associated with a specific time base. Applications can then use these callback functions to perform activities that are triggered by temporal events, such as a certain time being reached or a specified rate being achieved. The time base functions of the Movie Toolbox interact with clock components to schedule the invocation of these callback functions--your clock component is responsible for calling the callback function at its scheduled time.
The functions described in this section are called by the Movie Toolbox to support applications that define time base callback functions. For more information about time base callback functions, see the chapter "Movie Toolbox" in Inside Macintosh: QuickTime . Note that your clock component can delegate its callback events to another component by calling the Component Manager's DelegateComponent function, which is described in the chapter "Component Manager" in Inside Macintosh: More Macintosh Toolbox .
The ClockNewCallBack function allows your clock component to allocate the memory to support a new callback event. When an application discards a callback event, the Movie Toolbox calls your clock component's ClockDisposeCallBack function.
The Movie Toolbox calls your clock component's ClockCallMeWhen function when an application wants to schedule a callback event. When the callback function is to be invoked to service the event, the Movie Toolbox calls your component's ClockCancelCallBack function so that you can remove the callback event from the list of scheduled events.
Your component's ClockNewCallBack function allocates the memory for a new callback event. The Movie Toolbox calls this function when an application defines a time base callback event with the Movie Toolbox's NewCallBack function. The callback event created at this time is not active until it has been scheduled. An application schedules a callback event by calling the Movie Toolbox's CallMeWhen function.
Your component allocates the memory required to support the callback event. The memory must be in a locked block and must begin with a callback header structure. This structure is described in "Data Type," which begins on Data Type .
You should not call this function at interrupt time.
pascal QTCallBack ClockNewCallBack (ComponentInstance aClock,
TimeBase tb,
short callBackType);
Your clock component allocates the memory for the event and returns a pointer to that memory. If your clock component cannot satisfy the request or detects invalid or unsupported parameter values, you should set the QTCallBack result to nil .
Your component can allocate an arbitrarily large piece of memory for the callback event. That memory must begin with a callback header structure, which must be initialized to 0.
Your clock component's ClockCallMeWhen function schedules a callback event for invocation. The Movie Toolbox calls this function when an application schedules a callback event using the CallMeWhen function of the Movie Toolbox (described in the chapter "Movie Toolbox" in Inside Macintosh: QuickTime ).
The Movie Toolbox passes the parameter data from its CallMeWhen function to your component in the param1 , param2 , and param3 parameters to this function. Your clock component interprets these parameters based on the value of the callBackType parameter to the ClockNewCallBack function (see ClockNewCallBack ).
pascal ComponentResult ClockCallMeWhen (ComponentInstance aClock,
QTCallBack cb,
long param1,
long param2,
long param3);
The Movie Toolbox maintains control information about the callback event. Your clock component only needs to maintain the invocation schedule. For example, the Movie Toolbox saves the address of the callback event, its reference constant, and the value of the A5 register. In addition, the Movie Toolbox prevents applications from scheduling a single callback event more than once.
If your clock component successfully schedules the callback event, you should call the AddCallBackToTimeBase function (described on AddCallBackToTimeBase ) to add it to the list of callback events for the corresponding time base. If your component cannot schedule the callback event, it should return an appropriate error.
Your clock component's ClockCancelCallBack function removes the specified callback event from the list of scheduled callback events for a time base.
pascal ComponentResult ClockCancelCallBack
(ComponentInstance aClock,
QTCallBack cb);
The Movie Toolbox calls this function when an application cancels its callback event by calling CancelCallBack . The Movie Toolbox also calls this function whenever it executes the callback event, thus removing it from the list of scheduled callback events. The application is then responsible for rescheduling the event, if appropriate.
If your clock component successfully cancels the callback event, you should call the RemoveCallBackFromTimeBase function, described on RemoveCallBackFromTimeBase , so that the Movie Toolbox can remove the callback event from its list of scheduled events.
Your clock component's ClockDisposeCallBack function disposes of the memory associated with the specified callback event.
pascal ComponentResult ClockDisposeCallBack
(ComponentInstance aClock,
QTCallBack cb);
Clock components provide several functions that allow the Movie Toolbox to alert your component to changes in its environment. Three of these functions, ClockTimeChanged , ClockRateChanged , and ClockStartStopChanged , are associated with application callback functions and help your component determine whether to invoke the callback function. The fourth, the ClockSetTimeBase function, tells your clock component about the time base it is supporting.
The Movie Toolbox calls your component's ClockTimeChanged function whenever the callback's time base time value is set. The Movie Toolbox calls this function only if the qtcbNeedsTimeChanges flag is set to 1 in the callBackFlags field of the QuickTime callback header structure allocated by your clock component (see "Data Type," for more information).
pascal ComponentResult ClockTimeChanged
(ComponentInstance aClock,
QTCallBack cb);
The Movie Toolbox calls your component's ClockRateChanged function whenever the callback's time base rate changes. The Movie Toolbox calls this function only if the qtcbNeedsRateChanges flag is set to 1 in the callBackFlags field of the callback header structure in the QTCallBackHeader structure allocated by your clock component (see "Data Type," for more information about the callback header structure).
pascal ComponentResult ClockRateChanged (ComponentInstance aClock,
QTCallBack cb);
The Movie Toolbox calls your component's ClockStartStopChanged function whenever the start or stop time of the callback's time base changes. The Movie Toolbox calls this function only if the qtcbNeedsStartStop flag is set to 1 in the callBackFlags field of the callback header structure in the QTCallBackHeader structure allocated by your clock component (see "Data Type," for more information about the callback header structure).
pascal ComponentResult ClockStartStopChanged
(ComponentInstance aClock, QTCallBack cb,
Boolean startChanged,
Boolean stopChanged);
The Movie Toolbox calls your component's ClockSetTimeBase function when an application creates a time base that uses your clock component. The tb parameter indicates the time base that is associated with your clock.
pascal ComponentResult ClockSetTimeBase (ComponentInstance aClock,
TimeBase tb);
Your clock component may need to know its time base if the rate or time value of the time base can be changed without using Movie Toolbox functions. This could be the case if your clock supports an external clock. Under these circumstances, the Movie Toolbox cannot use the ClockRateChanged and ClockTimeChanged functions (described on ClockRateChanged and ClockTimeChanged , respectively) to alert your component to changes in its environment. Instead, your component can use the time base provided here to seed the GetFirstCallBack function, described on GetFirstCallBack , and then scan all its associated callback functions.
The Movie Toolbox provides a number of support functions for clock components. All of these functions help your component manage its associated callback functions. Your clock component may call any of these functions at interrupt time. These functions should only be called by clock components.
Use the AddCallBackToTimeBase function to add a callback event to the list of scheduled callback events maintained by the Movie Toolbox. You should use the RemoveCallBackFromTimeBase function to remove a callback event from the list.
When your clock component determines that it is time to invoke a callback function, you should use the ExecuteCallBack function to cause the Movie Toolbox to call the function.
If your clock component needs to scan all its associated callback events, you can use the GetFirstCallBack and GetNextCallBack functions.
Your clock component uses the AddCallBackToTimeBase function to place a callback event into the list of scheduled callback events. The Movie Toolbox maintains this list.
pascal OSErr AddCallBackToTimeBase (QTCallBack cb);
Your component should call the AddCallBackToTimeBase function when your ClockCallMeWhen function determines that your component can support the callback event (see "Using the Callback Functions," which begins on Using the Callback Functions , for more information about the ClockCallMeWhen function).
If your component does not call this function, the Movie Toolbox does not notify your component of time, rate, or stop and start changes (via the ClockRateChanged and ClockTimeChanged functions, described on ClockRateChanged and ClockTimeChanged , respectively).
When your clock component determines that it is time to execute a callback function, your component should call the ExecuteCallBack function.
pascal void ExecuteCallBack (QTCallBack cb);
This function handles all the details of invoking the callback function properly. For example, the ExecuteCallBack function queues the callback function correctly, according to the function's ability to execute at interrupt time (specified in the callBackType parameter to your ClockNewCallBack function, described on ClockNewCallBack ).
Before calling the application's function, the ExecuteCallBack function cancels the callback event. In this manner, the callback event is prevented from executing twice in succession. It is up to the application, or the callback function itself, to reschedule the callback event.
This function sets the A5 register to the value it contained at the time the callback event was scheduled when calling the callback function.
Your clock component should not release the memory associated with the callback event at this time. You should do so only in your ClockDisposeCallBack function (described on ClockDisposeCallBack ). This is particularly important when a callback function cannot execute at interrupt time, since the Movie Toolbox schedules such functions for invocation at a later time.
Your clock component uses the RemoveCallBackFromTimeBase function to remove a callback event from the list of scheduled callback events. The Movie Toolbox maintains this list.
pascal OSErr RemoveCallBackFromTimeBase (QTCallBack cb);
Your component should call the RemoveCallBackToTimeBase function when your ClockCancelCallBack function determines that your component can cancel the callback event (see "Using the Callback Functions," for more information about the ClockCancelCallBack function).
Your component should call the RemoveCallbackFromTimeBase function only for callback events that were successfully added to the schedule with the AddCallBackToTimeBase function (described on AddCallBackToTimeBase ).
The GetFirstCallBack function returns the first callback event associated with a specified time base. Your component can use this function, along with the GetNextCallBack function (described in the next section), to scan all callback events associated with a time base.
pascal QTCallBack GetFirstCallBack (TimeBase tb);
The GetFirstCallBack function returns the first callback event in the list managed for the specified time base. If there are no callback events associated with the time base, the QTCallBack result is set to nil . Your component cannot assume that the Movie Toolbox maintains the callback list in any particular order.
The GetNextCallBack function returns the next callback event associated with a specified time base. Your component can use this function, along with the GetFirstCallBack function (described in the previous section), to scan all callback events associated with a time base.
pascal QTCallBack GetNextCallBack (QTCallBack cb);
The GetNextCallBack function returns the next callback event in the list managed for the specified time base. If there are no more callback events associated with the time base, the returned QuickTime callback header structure is set to nil . Your component cannot assume that the Movie Toolbox maintains the callback list in any particular order .